package compile

import "fmt"

type Scope struct {
	Symbols        map[string]Symbol
	PackageEntries map[string]*PackageEntry
	Imports        []*ImportDeclare
}

func (scope *Scope) PutSymbol(name string, symbol Symbol) {
	scope.Symbols[name] = symbol
}

func (scope *Scope) PutPackageEntry(name string, entry *PackageEntry) {
	scope.PackageEntries[name] = entry
}

func (scope *Scope) String() string {
	var symStrItems, impStrItems []string

	for name, symbol := range scope.Symbols {
		symStrItems = append(symStrItems,
			fmt.Sprintf("%s : %s", name, symbol.String()))
	}

	for _, impDecl := range scope.Imports {
		impStrItems = append(impStrItems, dotPathToString(impDecl.ImportParts))
	}

	return fmt.Sprintf("Scope ")
}

type ClassFileScopeStack struct {
	base []*Scope
}

// return a new scope stack with 1 Scope object.
func newScopeStack() *ClassFileScopeStack {
	return &ClassFileScopeStack{
		base: []*Scope{new(Scope)},
	}
}

func (stack *ClassFileScopeStack) Push(scope *Scope) {
	stack.base = append(stack.base, scope)
}

func (stack *ClassFileScopeStack) Pop() *Scope {
	if len(stack.base) < 0 {
		return nil
	}
	tos := stack.base[len(stack.base)-1]
	stack.base = stack.base[:len(stack.base)-1]

	return tos
}

func (stack *ClassFileScopeStack) Tos() *Scope {
	if len(stack.base) > 0 {
		return stack.base[len(stack.base)-1]
	}
	return nil
}
